package com.turing.post.antimoney.impl;

import java.math.BigInteger;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;

import com.turing.post.antimoney.util.AlarmInfo;
import com.turing.post.antimoney.util.AlarmInfoDao;
import com.turing.post.antimoney.util.AlarmInfoDetail;
import com.turing.post.antimoney.util.AlarmInfoDetailDao;
import com.turing.post.antimoney.util.AlarmRule;
import com.turing.post.antimoney.util.AlarmRulesBusiness;
import com.turing.post.cardmanagement.util.ActivateCardDao;
import com.turing.post.common.util.PCPSCommonDao;
import com.turing.post.salesmanage.util.PersonalCustom;
import com.turing.post.salesmanage.util.PersonalCustomDao;
import com.turing.post.transaction.util.MchTradDetailDao;
import com.turing.post.util.PCPSApplicationException;
import com.turing.post.util.PCPSUtil;

/**
 * 同一实名制个人客户，不同卡号N天内刷卡消费累计超过N元
 * 
 * @author kangzhe
 * 
 */
@Remote
@Local
@Stateless(mappedName = "antimoney.impl.AlarmRule7")
public class AlarmRule7 implements AlarmRulesBusiness {

	@EJB(mappedName = "transaction.impl.MchTradDetailDaoImpl")
	private MchTradDetailDao mchTradDao;

	@EJB(mappedName = "cardmanagement.impl.ActivateCardDaoImpl")
	private ActivateCardDao accDao;

	@EJB(mappedName = "antimoney.impl.AlarmInfoDaoImpl")
	private AlarmInfoDao alarmInfoDaoImpl;

	@EJB(mappedName = "antimoney.impl.AlarmInfoDetailDaoImpl")
	private AlarmInfoDetailDao alarmInfoDetailDaoImpl;

	@EJB(mappedName = "common.impl.PCPSCommonDaoImpl")
	private PCPSCommonDao commonDaoImpl;

	@EJB(mappedName = "salesmanage.impl.PersonalCustomDaoImpl")
	private PersonalCustomDao pcDao;

	@Override
	@TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRES_NEW)
	public void runAlarmRules(String issueCompanyNo, Date tranDate,
			AlarmRule alarmRule) throws PCPSApplicationException {
		PCPSUtil.Log("执行预警规则:同一实名制个人客户，不同卡号N天内刷卡消费累计超过N元");
		// 1.取预警参数
		if (tranDate == null || alarmRule == null
				|| PCPSUtil.isEmpty(alarmRule.getRuleParameter())) {
			PCPSUtil.Log("预警规则为空或交易日期为空!");
			return;
		}
		String[] parameters = alarmRule.getRuleParameter().split(":");
		if (parameters.length <= 0 || PCPSUtil.isEmpty(parameters[0])) {
			PCPSUtil.Log("预警规则参数为空!");
			return;
		}
		// 2.计算起始交易日期,格式yyyy-mm-dd
		String startDate = null;
		String endDate = null;
		startDate = PCPSUtil.BeforeNowDate(tranDate, 0 - Integer
				.valueOf(parameters[0]));
		endDate = PCPSUtil.getPackedYMDString2(tranDate);
		// 3.取预警交易金额阀值
		BigInteger amount = BigInteger.ZERO;
		if (!PCPSUtil.isEmpty(parameters[1])) {
			amount = new BigInteger(parameters[1]);
		}

		// 4.发布预警信息
		releaseAlarm(issueCompanyNo, alarmRule, startDate, endDate, amount,
				tranDate);
		PCPSUtil.Log("执行完成!");
	}

	/**
	 * 发布预警信息
	 * 
	 * @param issueCompanyNo
	 * @param alarmRule
	 * @param startDate
	 * @param endDate
	 * @param amount
	 * @throws PCPSApplicationException
	 */
	private void releaseAlarm(String issueCompanyNo, AlarmRule alarmRule,
			String startDate, String endDate, BigInteger amount, Date tranDate)
			throws PCPSApplicationException {
		// 1.获取获取同一持卡人不同卡号集合
		List<Object[]> ownerCards = accDao
				.getActivateCardsOwnerInfo(issueCompanyNo);
		if (ownerCards == null || ownerCards.size() <= 0) {
			return;
		}
		int ownerCardsSize = ownerCards.size();
		Map<String, String> cardsMap = new HashMap<String, String>();
		String ownerId = "";
		String cardNo = "";
		Object[] obj = null;
		for (int i = 0; i < ownerCardsSize; i++) {
			obj = ownerCards.get(i);
			ownerId = obj[1].toString();
			cardNo = cardsMap.get(ownerId);
			if (cardsMap.containsKey(ownerId)) {
				cardsMap.put(ownerId, cardNo + "," + obj[0].toString());
			} else {
				cardNo = obj[0].toString();
				cardsMap.put(ownerId, cardNo);
			}
		}

		// 2.根据预警条件获取交易信息
		Object[] cardNos = cardsMap.keySet().toArray();
		for (int k = 0; k < cardsMap.size(); k++) {
			// 判断该集合是否满足金额限制
			if (!mchTradDao.isEnoughAmountCardsFromMchTradDetail(
					issueCompanyNo, startDate, endDate, cardsMap
							.get(cardNos[k]), amount)) {
				continue;
			}
			List<Object[]> mchTradList = mchTradDao
					.getRealNameCardFromMchTradDetail(issueCompanyNo,
							startDate, endDate, cardsMap.get(cardNos[k]));
			int listSize = 0;
			if (mchTradList != null && mchTradList.size() > 0) {
				listSize = mchTradList.size();
			}
			// 3.添加预警信息
			AlarmInfo alarmInfo = null;
			AlarmInfoDetail alarmInfoDetail = null;
			// 风险客户名称
			String riskCustomName = "";
			// 预警明细序号
			int seqno = 1;
			for (int i = 0; i < listSize; i++) {
				obj = mchTradList.get(i);
				if (!riskCustomName.equals(obj[0].toString())) {
					// 插入预警信息
					alarmInfo = new AlarmInfo();
					riskCustomName = obj[0].toString();
					seqno = 1;

					alarmInfo.setAlarmInfoId(alarmInfoDaoImpl
							.getMaxAlarmInfoId());
					alarmInfo.setAlarmRuleId(alarmRule.getAlarmRuleId());
					alarmInfo.setIssueCompanyNo(issueCompanyNo);
					alarmInfo.setAlarmTime(commonDaoImpl.getDatabaseSysTime());
					alarmInfo.setBranchNo(obj[1].toString());
					alarmInfo.setBranchName(obj[2].toString());
					alarmInfo.setRiskCustomName(riskCustomName);
					alarmInfo.setAlarmReason(alarmRule.getAlarmRuleDesc());
					alarmInfo.setDealStatus("0");
					alarmInfoDaoImpl.insertAlarmInfo(alarmInfo);

					// 更新风险客户等级为:中等风险客户
					PersonalCustom pc = pcDao
							.getPersonalCustomByPersonalId(new BigInteger(
									obj[6].toString()));
					pc.setRiskLevel(PersonalCustom.MID_CUSTOM);
					pcDao.updatePersonalCustom(pc);
				}

				// 3.插入预警明细
				alarmInfoDetail = new AlarmInfoDetail();
				alarmInfoDetail.setAlarmInfoId(alarmInfo.getAlarmInfoId());
				alarmInfoDetail.setSeqNo(seqno);
				seqno++;
				alarmInfoDetail.setBusinessType("3");
				alarmInfoDetail.setMerchantNo(obj[1].toString());
				alarmInfoDetail.setTranDate(tranDate);
				alarmInfoDetail.setTranSeqNo(obj[3].toString());
				alarmInfoDetailDaoImpl.insertAlarmInfoDetail(alarmInfoDetail);
			}
		}
	}
}
